//////////////////////////////////////////////////////////////////////////
// Constants
//////////////////////////////////////////////////////////////////////////
#define NETWORK_ALLOC_TAG					'sidN'
#define NETWORK_PACKET_EVENT_NAME			L"\\BaseNamedObjects\\NetworkPacketEvent"

//////////////////////////////////////////////////////////////////////////
// IO Control Codes
//////////////////////////////////////////////////////////////////////////
#define IOCTL_NETWORK_GET_PROTOCOL_HEADER					CTL_CODE_AST(1000)
#define IOCTL_NETWORK_NDIS_HOOK								CTL_CODE_AST(1001)
#define IOCTL_NETWORK_GET_NETWORK_PACKET					CTL_CODE_AST(1002)

//////////////////////////////////////////////////////////////////////////
// Functions
//////////////////////////////////////////////////////////////////////////
VOID InitializeNetwork();
VOID DisposeNetwork();
VOID FreeNetworkPacketItemCallback(PLIST_ENTRY pListEntry);
BOOLEAN ProcessIoCtlForNetwork(ULONG ioControlCode, PDEVICE_OBJECT deviceObject, PIRP irp, PIO_STACK_LOCATION irpStack);

VOID ProcessGetProtocolHeader(PIRP irp);
VOID ProcessNdisHook(PIRP irp);
VOID ProcessGetNetworkPacket(PIRP irp, PIO_STACK_LOCATION irpStack);

//////////////////////////////////////////////////////////////////////////
// Hook Functions
//////////////////////////////////////////////////////////////////////////
MINIPORT_SEND_NET_BUFFER_LISTS HookSendNetBufferLists;
PROTOCOL_RECEIVE_NET_BUFFER_LISTS HookReceiveNetBuferLists;

//////////////////////////////////////////////////////////////////////////
// Protocol Handler Functions
//////////////////////////////////////////////////////////////////////////
PROTOCOL_BIND_ADAPTER_EX NdisprotBindAdapter;
PROTOCOL_OPEN_ADAPTER_COMPLETE_EX NdisprotOpenAdapterComplete;
PROTOCOL_UNBIND_ADAPTER_EX NdisprotUnbindAdapter;
PROTOCOL_CLOSE_ADAPTER_COMPLETE_EX NdisprotCloseAdapterComplete;
PROTOCOL_OID_REQUEST_COMPLETE NdisprotRequestComplete;
PROTOCOL_STATUS_EX NdisprotStatus;
PROTOCOL_SEND_NET_BUFFER_LISTS_COMPLETE NdisprotSendComplete;
PROTOCOL_RECEIVE_NET_BUFFER_LISTS NdisprotReceiveNetBufferLists;
PROTOCOL_NET_PNP_EVENT NdisprotPnPEventHandler;

//////////////////////////////////////////////////////////////////////////
// Structures
//////////////////////////////////////////////////////////////////////////
typedef struct _REFERENCE_EX
{
	KSPIN_LOCK                  SpinLock;
	USHORT                      ReferenceCount;
	BOOLEAN                     Closing;
	BOOLEAN						ZeroBased;
	ULONG_PTR					RefCountTracker;
} REFERENCE_EX, *PREFERENCE_EX;

typedef	struct _NDIS_PROTOCOL_BLOCK
{
	NDIS_OBJECT_HEADER	Header;
	ULONG_PTR	ProtocolDriverContext;
	ULONG_PTR	NextProtocol;
	ULONG_PTR	OpenQueue;
	REFERENCE_EX	Ref;
	UCHAR	MajorNdisVersion;
	UCHAR	MinorNdisVersion;
	UCHAR	MajorDriverVersion;
	UCHAR	MinorDriverVersion;
	ULONG	Reserved;
	ULONG	Flags;
	UNICODE_STRING	Name;
} NDIS_PROTOCOL_BLOCK, *PNDIS_PROTOCOL_BLOCK;

typedef struct _NDIS_HOOK_REQUEST
{
	NDIS_HANDLE NdisProtocolHandle;
	NDIS_HANDLE NdisMiniportHandle;
	ULONG_PTR SendFuncAddress; // original send function
	ULONG_PTR RecvFuncAddress; // original recv function
	ULONG_PTR HookSendAddress;
	ULONG_PTR HookRecvAddress;
	BOOLEAN IsInstall;
} NDIS_HOOK_REQUEST, *PNDIS_HOOK_REQUEST;

typedef struct _NETWORK_PACKET_ITEM_DATA {
	LONG Type;
	ULONG Size;
	PVOID Content;
} NETWORK_PACKET_ITEM_DATA, *PNETWORK_PACKET_ITEM_DATA;

typedef struct _NETWORK_PACKET_ITEM {
	LIST_ENTRY ListEntry;
	NETWORK_PACKET_ITEM_DATA Data;
} NETWORK_PACKET_ITEM, *PNETWORK_PACKET_ITEM;
